﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;

namespace WeLinkApi.Common
{
    public static class HttpWebRequestHelper
    {
        #region PostJson方法
        /// <summary>
        /// post传递json数据
        /// 无token时
        /// </summary>
        /// <param name="url">要请求的URL地址</param>
        /// <param name="postData">json数据</param>
        /// <returns></returns>
        public static string PostJsonToUrl(string url, string postData)
        {
            string result = "";
            //解决请求被中止：无法建立SSL / TLS安全通道问题(.net framework 4.0)
            System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

            req.Method = "POST";
            req.Timeout = 60000;//设置请求超时时间，单位为毫秒
            req.ContentType = "application/json";
            req.UserAgent = "Apache-HttpClient/4.5.3 (Java/1.8.0_191)";
            SetHeaderValue(req.Headers, "Connection", "keep-alive");
            SetHeaderValue(req.Headers, "X-Request-ID", Guid.NewGuid().ToString("N"));
            SetHeaderValue(req.Headers, "Accept-Language", "zh_CN");

            byte[] data = Encoding.UTF8.GetBytes(postData);

            req.ContentLength = data.Length;
            ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
            }

            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

            Stream stream = resp.GetResponseStream();

            //获取响应内容
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }

            return result;
        }


        /// <summary>
        /// post传递json数据
        /// </summary>
        /// <param name="url">要请求的URL地址</param>
        /// <param name="postData">json数据</param>
        /// <param name="token">token</param>
        /// <returns></returns>
        public static string PostJsonToUrlByToken(string url, string postData, string token)
        {
            string result = "";

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

            req.Method = "POST";
            req.Timeout = 60000;//设置请求超时时间，单位为毫秒
            req.ContentType = "application/json";
            req.UserAgent = "Apache-HttpClient/4.5.3 (Java/1.8.0_191)";
            SetHeaderValue(req.Headers, "X-Auth-Token", token);
            SetHeaderValue(req.Headers, "Connection", "keep-alive");
            SetHeaderValue(req.Headers, "X-Request-ID", Guid.NewGuid().ToString("N"));
            SetHeaderValue(req.Headers, "Accept-Language", "zh_CN");

            byte[] data = Encoding.UTF8.GetBytes(postData);

            req.ContentLength = data.Length;
            ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
            }

            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

            Stream stream = resp.GetResponseStream();

            //获取响应内容
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }

        /// <summary>
        /// get方法
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string SendGetRequest(string url, string token)
        {
            if (string.IsNullOrEmpty(url))
                throw new ArgumentNullException("url");
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "GET";
            request.Timeout = 60000;
            request.UserAgent = "Apache-HttpClient/4.5.3 (Java/1.8.0_191)";
            SetHeaderValue(request.Headers, "X-Auth-Token", token);
            SetHeaderValue(request.Headers, "Connection", "keep-alive");
            SetHeaderValue(request.Headers, "user-agent", "WeLink-desktop");
            ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                return ReadResponse(response);
            }
        }

        /// <summary>
        /// Delete方法
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string SendDeleteRequest(string url, string token)
        {
            if (string.IsNullOrEmpty(url))
                throw new ArgumentNullException("url");
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "DELETE";
            request.Timeout = 60000;
            request.UserAgent = "Apache-HttpClient/4.5.3 (Java/1.8.0_191)";
            SetHeaderValue(request.Headers, "X-Auth-Token", token);
            SetHeaderValue(request.Headers, "Connection", "keep-alive");
            SetHeaderValue(request.Headers, "user-agent", "WeLink-desktop");
            ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                return ReadResponse(response);
            }
        }

        /// <summary>
        /// put传递json数据,修改
        /// </summary>
        /// <param name="url">要请求的URL地址</param>
        /// <param name="postData">json数据</param>
        /// <param name="token">token</param>
        /// <returns></returns>
        public static string PutJsonToUrlByToken(string url, string postData, string token)
        {
            string result = "";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

            req.Method = "PUT";
            req.Timeout = 60000;//设置请求超时时间，单位为毫秒
            req.ContentType = "application/json";
            req.UserAgent = "Apache-HttpClient/4.5.3 (Java/1.8.0_191)";
            SetHeaderValue(req.Headers, "X-Auth-Token", token);
            SetHeaderValue(req.Headers, "Connection", "keep-alive");
            SetHeaderValue(req.Headers, "Accept-Language", "zh_CN");

            byte[] data = Encoding.UTF8.GetBytes(postData);

            req.ContentLength = data.Length;
            ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
            }

            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

            Stream stream = resp.GetResponseStream();

            //获取响应内容
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }

        public static string PostJsonToUrlWeLink(string url, string postData)
        {
            string result = "";

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

            req.Method = "POST";
            req.Timeout = 60000;//设置请求超时时间，单位为毫秒
            req.ContentType = "application/json";

            byte[] data = Encoding.UTF8.GetBytes(postData);

            req.ContentLength = data.Length;
            ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
            }

            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

            Stream stream = resp.GetResponseStream();

            //获取响应内容
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }

            return result;
        }

        public static string PostUrlWeLinkNoJson(string url, string token)
        {
            string result = "";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

            req.Method = "Get";
            req.Timeout = 60000;//设置请求超时时间，单位为毫秒
            SetHeaderValue(req.Headers, "x-wlk-Authorization", token);
            ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
            using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
            {
                return ReadResponse(response);
            }
        }

        /// <summary>
        /// WeLink get方法
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string SendGetToWeLinkRequest(string url, string token)
        {
            if (string.IsNullOrEmpty(url))
                throw new ArgumentNullException("url");
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "GET";
            request.Timeout = 60000;
            request.UserAgent = "Apache-HttpClient/4.5.3 (Java/1.8.0_191)";
            SetHeaderValue(request.Headers, "x-wlk-Authorization", token);
            SetHeaderValue(request.Headers, "Connection", "keep-alive");
            SetHeaderValue(request.Headers, "user-agent", "WeLink-desktop");
            ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                return ReadResponse(response);
            }
        }

        /// <summary>
        /// post传递json数据,异步同步
        /// </summary>
        /// <param name="url">要请求的URL地址</param>
        /// <param name="postData">json数据</param>
        /// <param name="token">token</param>
        /// <returns></returns>
        public static string PostJsonToUrlByTokenWeLink(string url, string postData, string token)
        {
            string result = "";

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

            req.Method = "POST";
            req.Timeout = 60000;//设置请求超时时间，单位为毫秒
            req.ContentType = "application/json";
            SetHeaderValue(req.Headers, "x-wlk-Authorization", token);
            SetHeaderValue(req.Headers, "Accept-Charset", "UTF-8");

            byte[] data = Encoding.UTF8.GetBytes(postData);

            req.ContentLength = data.Length;
            ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
            }

            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

            Stream stream = resp.GetResponseStream();

            //获取响应内容
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }

        #endregion

        #region 通用方法

        /// <summary>
        /// 读取响应内容。
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        private static string ReadResponse(HttpWebResponse response)
        {
            if (response == null) return string.Empty;
            Stream strem = null;
            if (response.Headers["Content-Encoding"] == "gzip")
                strem = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress);
            else
                strem = response.GetResponseStream();

            if (strem == null) return string.Empty;
            using (StreamReader reader = new StreamReader(strem))
            {
                return reader.ReadToEnd();
            }
        }


        public static void SetHeaderValue(WebHeaderCollection header, string name, string value)
        {
            var property = typeof(WebHeaderCollection).GetProperty("InnerCollection", BindingFlags.Instance | BindingFlags.NonPublic);
            if (property != null)
            {
                var collection = property.GetValue(header, null) as NameValueCollection;
                collection[name] = value;
            }
        }
    }


    /// <summary>
    /// 解决连接时检验没有证书的错误
    /// </summary>
    internal class AcceptAllCertificatePolicy : ICertificatePolicy
    {
        public AcceptAllCertificatePolicy()
        {
        }

        public bool CheckValidationResult(ServicePoint sPoint,
           X509Certificate cert, WebRequest wRequest, int certProb)
        {
            // Always accept
            return true;
        }
    }
    #endregion

}
